﻿using Avalon.Core.Data.Templates;
using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.Validation;
using System.Diagnostics;

namespace Avalon.Core.Data
{
    public partial class BaseDbContext : DbContext
    {
        public DbSet<AvalonExtension> Extensions { get; set; }
        public DbSet<AvalonExtensionValue> ExtensionValues { get; set; }
        public DbSet<AvalonUser> Users { get; set; }
        public DbSet<AvalonRole> Roles { get; set; }
        public DbSet<AvalonPermission> Permission { get; set; }
        public DbSet<AvalonView> Views { get; set; }
        public DbSet<AvalonViewRendererGroup> ViewRendererGroups { get; set; }
        public DbSet<AvalonEntity> Entities { get; set; }

        public BaseDbContext() { }
        public BaseDbContext(string connectionName) : base(connectionName) { }

        public override int SaveChanges()
        {
            ///foreach entity in the entity tracker, save the changes
            foreach (var entity in this.ChangeTracker.Entries())
            {
                ///Set the id of the entity if this id is empty
                if (entity.Entity is IEntity &&
                    (entity.Entity as IEntity).Id == Guid.Empty &&
                    entity.State == System.Data.EntityState.Added)
                {
                    (entity.Entity as IEntity).Id = Guid.NewGuid();
                }

                if (entity.Entity is IAuditable)
                {
                    ///Get the user name, use system if there is no logged in user
                    string userName = "SYSTEM";

                    ///If the entity state is State.Added set the date created 
                    ///and who created the entity.
                    if (entity.State == System.Data.EntityState.Added)
                    {
                        (entity.Entity as IAuditable).CreatedOn = DateTime.Now;
                        (entity.Entity as IAuditable).CreatedBy = userName;
                    }
                    ///If the entity state is State.Modified set the date modified 
                    ///and the person who modified it
                    else if (entity.State == System.Data.EntityState.Modified)
                    {
                        (entity.Entity as IAuditable).ModifiedOn = DateTime.Now;
                        (entity.Entity as IAuditable).ModifiedBy = userName;
                    }
                }
            }

            try
            {
                return base.SaveChanges();
            }
            catch (DbEntityValidationException ex)
            {
#if DEBUG
                foreach (var validationErrors in ex.EntityValidationErrors)
                {
                    foreach (var validationError in validationErrors.ValidationErrors)
                    {
                        Trace.TraceInformation("Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage);
                    }
                }
#endif
            }
            catch (DbUpdateException ex)
            {
                Trace.TraceInformation(ex.InnerException.InnerException.Message.ToString());
            }
            return -1;
        }
    }
}
